//--------------------
// SPI_Wakeup_Master.c
//--------------------

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "LPC8xx.h"
#include "spi.h"
#include "syscon.h"
#include "swm.h"
#include "utilities.h"
#include "gpio.h"
#include "uart.h"
#include "chip_setup.h"
#include "serial_unit.h" // add by zwr
#include "i2c.h"
extern double tdc6500();
extern void setup_debug_uart(void);
extern void dac1220_set(unsigned char data1,unsigned char data2,unsigned char data3);
extern void select_mode_vcc(unsigned char data);
extern void delay1ms(void);  // delay 86*13*12/30 = 0.472ms
extern void delay(int xx); //50 * xx * 12 * 1 /30 us = 20 * xx us
extern void delay_us(int time_us ); // time_us * 4 us
extern void delay_ms(int time_ms);  // zwr 44-48ms * time_ms ?
extern void DELAY(int z);
extern void dac1220_init(void);
extern void zwr_dac1220_init(void);

extern void WriteOneByte(unsigned char command);
extern void dac1220_set(unsigned char data1,unsigned char data2,unsigned char data3);
extern void DAC1220_writeCode(uint32_t code);
extern void DAC1220_writeV(double v);

FunctionalState SHT2x_Calc_T(void);
FunctionalState SHT2x_Calc_RH(void);
float temperatureC;
float humidityRH;
double TT;
volatile enum {false, true} handshake;
////数据驱动API////
extern int sign(double x);
extern double round(double r);
extern void data_driver();

unsigned char MySPIByte(unsigned char sdat,unsigned char cs,unsigned char rxignore);

const char config_register[17] = {0x83,0x03,0x00,0x40,0x0D,0x03,0xC0,0xA3,0xA1,0x13,0x00,0x0A,0xCC,0x05,0xF1,0x7D,0x04};
int irq_flag = 0;
unsigned char rx_buffer[10] = {0};
uint32_t rx_char_counter = 0;

int print_flag = 0;
/* test voltage */
double Vcc = 1.684;
/////////////算法参数定义////////
//控制器参数
double eita = 0.5;
double miu = 0.05;
double rou= 0.5;
double lamda = 0.05;
double epsilon = 0.00001;

//控制器伪偏导数初值
double fai1=0.3,fai2=0;
double error2 = 0;

//double td = 4000.072540;//期望值
//double td = 4000.183598;//期望值
//double td =4000.072598;      ---->40.001 081
//double td = 4000.183098;//期望值  --->39.999 979 288
 // double td = 4000.183120; //期望值  --->39.999 972 227  -28
 //double td = 4000.162120; //期望值  --->  39.999 984 234 -16
 // double td = 4000.142120; //期望值  --->  40.000 367 192 +367
 //double td =  4000.152120;  //期望值  --->  40.000 270 192 +270
 //  double td =  4000.160120;   //期望值  --->  40.000 181 192 +181
 // double td =  4000.162085;   //期望值  --->  40.000 210 192 +210
   double td =  4000.182015;     //期望值  --->    40.000 006 852 +6
//double t1=td;
   // 10 - 15
   /*
    *  double td =  4000.183015;     //期望值  --->    39.999 850 852 -150
    *	double td =  4000.163015;    //期望值  --->    40.000 053 052 +50
    *   double td =  4000.168015;     //期望值  --->   39.999 990 852 -10
    *
    *
    */

   // 10 - 19
   /*
    *  double td =  4000.168015;     //期望值  --->    40.000 155 852 +155

    *
    *
    */

double yd = 0; //PPB
double y1=0,y2=0,y3=0;

double dac_data1=524287,dac_data2=0;//类型可能要改 unsigned int
double tdc_data=0;
double du1=0,du2= 0;//电压数据差
double sum=0;
/////////////////////////////////
#define SPIBAUD  1000000
#define SCK_PIN  P0_24
#define MOSI_PIN P0_25
#define SSEL_PIN P0_21
#define BUFFER_LIMIT 65

/*   iic pin & reg */
#define I2CSCL_PIN         P0_10         // P0_10 for I2C0
#define I2CSCL_IOCON_REG   PIO0_10
#define I2CSDA_PIN         P0_11         // P0_11 for I2C0
#define I2CSDA_IOCON_REG   PIO0_11

void data_inti();
void select_mode_td(unsigned char data);
void select_mode_vcc(unsigned char data);
/* expirement */
int dac_control = 0;  // 0x60 enable
double dac_value = 0;
double tdc_sum = 0;

int td_control = 1;  //0x61 enbale

void UART0_IRQHandler()
{
	unsigned char temp;
	temp = LPC_USART0->RXDAT ; //接收器数据寄存器。 包含收到的最后一个字符。
	if(temp == 0x60){
		dac_control = 1;
		td_control = 0;
		return;
	}else if(temp == 0x61){
		td_control = 1;
		dac_control = 0;
		return;
	}
	rx_buffer[0] = temp;        // Append the current character to the rx_buffer
	printf("irq == 1 !!\n");
	irq_flag = 1;
  if (temp == 0xFA) {                       // CR (carriage return) is current character. End of string.
 // rx_buffer[rx_char_counter+1] = 0x0A;    // Append a new line character to rx_buffer.
 // rx_buffer[rx_char_counter+2] = 0x00;    // Append a NUL terminator character to rx_buffer to complete the string.
 // WaitForUART0txRdy;                      // Wait for TXREADY
 // LPC_USART0->TXDAT  = 0x0A;              // Echo a NL (new line) character to the terminal.
    handshake = true;                       // Set handshake for main()
    rx_char_counter = 0;                    // Clear array index counter
    irq_flag = 1 ;
  }
  else {                                  // Current character is not CR, keep collecting them.
    rx_char_counter++;                      // Increment array index counter.
    if (rx_char_counter == BUFFER_LIMIT)  // If the string overruns the buffer, stop here before all hell breaks lose.
    	rx_char_counter =0;
 }
	return;
}
/*
void UART0_IRQHandler() {
	//unsigned char rx_char_counter = 0;   zwr
	unsigned char rx_temp;
	 //LPC_USART0->INTENSET = RXRDY;
	rx_temp = LPC_USART0->RXDAT; //接收器数据寄存器。 包含收到的最后一个字符。
	printf("\rReceived a char : %c\n\r",rx_temp);
	rx_buffer[rx_char_counter] = rx_temp;        // Append the current character to the rx_buffer
	if (rx_temp == 0x0A) {                       // CR (carriage return) is current character. End of string.
   //   rx_buffer[rx_char_counter+1] =  0x0A;    // Append a new line character to rx_buffer.
   //  rx_buffer[rx_char_counter+2] = 0x00;      // Append a NUL terminator character to rx_buffer to complete the string.
   //   WaitForUART0txRdy;                      // Wait for TXREADY
   //   LPC_USART0->TXDAT  = 0x0A;              // Echo a NL (new line) character to the terminal.
		handshake = true;                       // Set handshake for main()
		rx_char_counter = 0;                    // Clear array index counter
		irq_flag = 1;
	}
	else {                                  // Current character is not CR, keep collecting them.
		//printf("\rReceived a char : %c\n\r",rx_buffer[rx_char_counter]);
		rx_char_counter++;                      // Increment array index counter.
		if (rx_char_counter == 10)  		// If the string overruns the buffer, stop here before all hell breaks lose.
			rx_char_counter = 0;
	}

	return;
}*/
/*
int main(void) {


		  setup_debug_uart();
		  LPC_SYSCON->SYSAHBCLKCTRL[0] |= (SPI0|SWM|IOCON|GPIO1);
		  LPC_SYSCON->SYSAHBCLKCTRL[0] |= GPIO0;   // Turn on clock to GPIO0



	      for(int i = 0; i<100; i++){
	    	    printf("\r0. please scanf a char: \n\r");
	    	    printf("1. please scanf a char: \n\r");
	    	    printf("2. please scanf a char: \n");
	      }
	      while(1){


	      }

}
*/


int main(void) {
	setup_debug_uart();
	// Enable clocks to relevant peripherals
	LPC_SYSCON->SYSAHBCLKCTRL[0] |= (SPI0|SWM|IOCON|GPIO1|GPIO);
	LPC_SYSCON->SYSAHBCLKCTRL[0] |= GPIO0;   // Turn on clock to GPIO0

	// GPIOInit();  //GPIO初始化  有问题
	LPC_SYSCON->PRESETCTRL[0] &= (~(1<<6) & ~(1<<20));
	LPC_SYSCON->PRESETCTRL[0] |= ~(~(1<<6) & ~(1<<20));

	/* iic init setting */
	 LPC_SWM->PINENABLE0 |= (I2C0_SCL | I2C0_SDA);  //disable 	  LPC_SWM->PINENABLE0 |= (1<<13|1<<12);
	 LPC_IOCON->I2CSCL_IOCON_REG |= 1<<10; //使P0_10为开漏
	 LPC_IOCON->I2CSDA_IOCON_REG |= 1<<10;//使P0_11为开漏
	 I2CSCL_H;
	 I2CSDA_H;
	 LPC_GPIO_PORT->SET0  = (1<<I2CSCL_PIN)|(1<<I2CSDA_PIN);  //set bit = 1;
	 LPC_GPIO_PORT->DIR0 |= (1<<I2CSCL_PIN)|(1<<I2CSDA_PIN);  //output mode

	/*  DAC1220 setting  */
	GPIOSetDir( 0, 20, 1 );
	GPIOSetDir( 0, 21, 1 );
	GPIOSetDir( 0, 22, 1 );
	CLK_L;
	CS_L;
	//dac1220_init();  //annotation by zwr
	zwr_dac1220_init();

	/* AS6500 TDC's SPI interface configure  spi0  is used for tdc module */
	// Configure the SWM (see peripherals_lib and swm.h)
	ConfigSWM(SPI0_SCK,  P0_6); //将一个引脚(由其GPIO端口和位数指定)连接到一个功能上。
	ConfigSWM(SPI0_MOSI, P0_7); ////#define P0_6    6  #define P0_7      7
	ConfigSWM(SPI0_MISO, P1_18);  //SPI0_MISO 17   50
	ConfigSWM(SPI0_SSEL0,P1_7 );  //#define P1_7   39

	// Give SPI0 a reset
	LPC_SYSCON->PRESETCTRL[0] &= (SPI0_RST_N);
	LPC_SYSCON->PRESETCTRL[0] |= ~(SPI0_RST_N);
	// Enable main_clk as function clock to SPI
	LPC_SYSCON->SPI0CLKSEL = FCLKSEL_MAIN_CLK;

	// Get main_clk frequency
	SystemCoreClockUpdate();
	// Configure the SPI master's clock divider (value written to DIV divides by value+1)

	LPC_SPI0->DIV = (main_clk/SPIBAUD) - 1;
	// Configure the CFG register:
	// Enable=true, master, no LSB first, CPHA=0, CPOL=0, no loop-back, SSEL active low
	LPC_SPI0->CFG = CFG_ENABLE | CFG_MASTER | CFG_CPHA;//CPHA=1, CPOL=0？？？？
	// Configure the SPI delay register (DLY)
	// Pre-delay = 0 clocks, post-delay = 0 clocks, frame-delay = 0 clocks, transfer-delay = 0 clocks
	LPC_SPI0->DLY = 0x0000;
	// Configure the SPI control register
	// Master: End-of-frame true, End-of-transfer true, RXIGNORE true, LEN 8 bits.
	LPC_SPI0->TXCTL = CTL_EOF | CTL_EOT | CTL_LEN(8);//1<<16可能有问题

	/* TDC1_SPI_INT*/
	GPIOSetDir(0,0,0);//配置中断引脚为输入GPIOSetDir( uint32_t portNum, uint32_t bitPosi, uint32_t dir )  (1 out, 0 input)
	GPIOGetPinValue(0, 0);

	GPIOSetDir( 1, 17, 1 );//as6500 rst_id  (1 out, 0 input)
	GPIOSetBitValue( 1, 17, 0);// rst_id = 0

	GPIOSetDir( 1, 0, 1 );//FPGA_begin sigal
	GPIOSetBitValue( 1, 0, 0);
	printf("Init ok\n");
	while(1)
	{
		//if(irq_flag){
		  //dac1220_set(0xFF,0x00,0x00);
		  //tdc6500();
		  if(SHT2x_Calc_T())   //SHT2x_Calc_T()
		  {

					  	//	printf("OK\r\n");
					  	printf("tempture %f\r\n",temperatureC);
					  	//OLED_shuji(38,17,(s8)(temperatureC));
					  	//delay_ms(1000);
					  	/*Êª¶È²âÊÔ*/
		  }
		 if(SHT2x_Calc_RH()) {
				 	   printf("humdity %f\r\n",humidityRH);
				 	  // printf("AS6500 Freq %lf\r\n",TT);
				 	  DELAY(2000);//DELAY(20000);
		 }

		 if(dac_control == 1){//0x60  1.***
			for(int i=0;i<10;i++){
				tdc_data=tdc6500(); // measure period  原来只读了两次，现在变成读取四次了，ppb误差应该为e9但是龙写的e10
				tdc_sum = tdc_data + tdc_sum;
			}
			tdc_sum = tdc_sum / 10;
			printf("1. *************************************\n");
			printf("1. AS6500 measure period %lf us\r\n",tdc_sum);
			tdc_sum = 0;
			if(irq_flag == 1){
					select_mode_vcc(rx_buffer[0]);
					irq_flag = 0;
			}
		 }
		 else if(td_control == 1){//0x61  2. *****
			data_driver();
			if(irq_flag == 1){
				select_mode_td(rx_buffer[0]);
				irq_flag = 0;
			}
		 }


	}// end of while(1)

}  // end of main
void select_mode_vcc(unsigned char data){
	irq_flag = 0;
	printf("1. dac_value before modify : %lf \n",dac_value);
	unsigned char buf_hex[3]={0};

	if(data == 0x03){
		dac_value += 50;  //vcxo + 1hz
	}else if(data == 0x04){
		dac_value -= 50;
	}

	if(data == 0x05){
		dac_value += 500; //vcxo + 10hz
	}else if(data == 0x06){
		dac_value -= 500;
	}

	if(data == 0x07){
		dac_value += 5000; //vcxo + 100hz
	}else if(data == 0x08){
		dac_value -= 5000;
	}

	if(data == 0x09){
		dac_value += 50000; //vcxo_vcc +0.44v  vcxo_vcc +0.275v  vcxo + 1000hz
	}else if(data == 0x0a){
		dac_value -= 50000;
	}


	if(data == 0x0b){
			dac_value += 33659; //dac_vcc +0.16v vcxo_vcc +0.1v
	}else if(data == 0x0c){
			dac_value -= 33659; //dac_vcc -0.16v vcxo_vcc -0.1v
	}

	if ( dac_value>16777200 ){
		dac_value = 16777200;
		printf("1. dac value too big\n");
	}

	if ( dac_value<0 ){
		 dac_value = 0;
		 printf("1. dac value too small\n");
	}

 	buf_hex[0]=(unsigned int)(dac_value*16)&0xff;
   	buf_hex[1]=((unsigned int)(dac_value*16)>>8)&0xff;
   	buf_hex[2]=((unsigned int)(dac_value*16)>>16)&0xff;
   	dac1220_set(buf_hex[2],buf_hex[1],buf_hex[0]);
	printf("1. dac value modify success\n");
	printf("1. dac value after modify : %lf  dac_vcc = %lf  vcxo_vcc = %lf\n",dac_value,dac_value/0xfffff*5,dac_value/0xfffff*5/1.6);
	return;
}
/*
void select_mode_vcc(unsigned char data){
	irq_flag = 0;
	printf("Vcc before modify : %lf \n",Vcc);
	if(data == 0x01){
		dac1220_init();
		return;
	}else if(data == 0x02){
		zwr_dac1220_init();
		return;
	}

	if(data == 0x03){
		Vcc += 0.1;
	}else if(data == 0x04){
		Vcc -= 0.1;
	}
	if(data == 0x05){
		Vcc =Vcc +  0.01;

	}else if(data == 0x06){
		Vcc -= 0.01;
	}
	if(data == 0x07){
		Vcc += 0.001;
	}else if(data == 0x08){
		Vcc -= 0.001;
	}
	if(data == 0x09){
		Vcc += 0.0001;
	}else if(data == 0x0a){
		Vcc -= 0.0001;}
	printf("Vcc modify success\n");
	printf("Vcc after modify : %lf \n",Vcc);
	return;
}*/

void select_mode_td(unsigned char data){
	irq_flag = 0;
	printf("2. td_value before modify : %lf \n",td);
	static double td_tem = 4000.182015;;
	/*          0.1       */
	if(data == 0x50){
		td_tem = td_tem + 0.1;

	}else if(data == 0x51){
		td_tem = td_tem - 0.1;

	}
/*          0.01       */
	if(data == 0x52){
		td_tem = td_tem + 0.01;

	}else if(data == 0x53){
		td_tem = td_tem -0.01;
		}

	/*           0.001       4000.168 015;   */
	if(data == 0x54){
		td_tem = td_tem + 0.001;

		}else if(data == 0x55){
			td_tem = td_tem - 0.001;

		}

	/*     0.0001       */
	if(data == 0x56){
		td_tem = td_tem + 0.0001;
	}else if(data == 0x57){
		td_tem = td_tem - 0.0001;
	}
	/*     0.00001       */
	if(data == 0x58){
		td_tem = td_tem + 0.00001;

	}else if(data == 0x59){
		td_tem = td_tem - 0.00001;
	}

	if(data == 0x5A){
		printf("**************************\n");
		printf("\rAS6500 Frequency : %10.6f\n\r", TT);
		//printf("%rADC voltage: %lf\n\r",DAC1);
		printf("init success init_td : %lf\n",td);
		while(1){}
	}
	td = td_tem;
	printf("2. td value modify success\n");
	printf("2. td_value after modify : %lf \n",td);
	data_inti();
	return;
}

void data_inti(){

	//控制器参数
	 eita = 0.5;
	 miu = 0.05;
	 rou= 0.5;
	 lamda = 0.05;
	 epsilon = 0.00001;
	//控制器伪偏导数初值
	 fai1=0.3,fai2=0;
	error2 = 0;

	//double td = 4000.072540;//期望值
	//double td = 4000.173598;//期望值
	//td =  4000.182015;
	//double t1=td;
	 yd = 0; //PPB
	 y1=0,y2=0,y3=0;
	 dac_data1=524287,dac_data2=0;//类型可能要改 unsigned int
	 tdc_data=0;
	 du1=0,du2= 0;//电压数据差
	 sum=0;
}

unsigned char MySPIByte(unsigned char sdat,unsigned char cs,unsigned char rxignore)
{   //cs=0 or 1, 1 means end transmit data ,rxignore=0 or 1,1 means ignore recived data
	//sdat means the sending data
	unsigned char rdat=0;
	if(cs)  //CS=1 after send dat
	{
		LPC_SPI0->TXCTL |= (1<<20); //EOT=1
	}
	else   //CS=0 after send dat
	{
		LPC_SPI0->TXCTL &= ~(1<<20); //EOT=0
	}
	if(rxignore)
	{
		LPC_SPI0->TXCTL |=(1<<22); //Ignore
	}
	else
	{
		LPC_SPI0->TXCTL &= ~(1<<22); //Read data
	}
	while((LPC_SPI0->STAT & (STAT_TXRDY))==0); //Wait Transmit Rdy
	LPC_SPI0->TXDAT=sdat;
	if(!rxignore)
	{
		while((LPC_SPI0->STAT & (STAT_RXRDY))==0); //Wait Recv Rdy  1
		rdat=LPC_SPI0->RXDAT;
	}
	return rdat;
}

FunctionalState SHT2x_Calc_T(void)/* tempture */
{
	 	 unsigned char length=0;
		 uint8_t Tdata[3]={0}; // uint8_t == unsiged char
		 if(!I2C_Start()){
			 printf("start error\n");
			 return DISABLE;
		 }
	     I2C_SendByte(I2C_ADR_W);  // begin write signal,sensor I2C address + write bit
	     if(!I2C_WaitAck())
	     {
	    	I2C_Stop();
			return DISABLE;
		}
	    I2C_SendByte(TRIG_T_MEASUREMENT_POLL);     // 0xF3  触发 温度 测量 ，非保持主机 命令
	    I2C_WaitAck();//判断是否收到了ack
		delay_us(20);
		I2C_Stop();
		do
		{
			DELAY(100);
			I2C_Start();
			I2C_SendByte(I2C_ADR_R);
		}while(!I2C_WaitAck());//循环读取，直到从机响应获取温度信息的命令

			Tdata[0]=I2C_ReceiveByte();		//printf("%c\r\n",Tdata[0]);
			I2C_Ack();
			Tdata[1]=I2C_ReceiveByte();     //printf("%c\r\n",Tdata[1]);
			I2C_NoAck();
			I2C_Stop();//结束一次温度的读取

			temperatureC= (-46.85 + (175.72/65536 )*((float)((((unsigned short)Tdata[0]<<8)+(unsigned short)Tdata[1])&0xfffc)));
			//temperatureC = 175.72 * (((((int) Tdata[0]) << 8) + Tdata[1]) / 65536.0) - 46.85;

			return ENABLE;
};
FunctionalState SHT2x_Calc_RH(void)/* humdity */
{
   unsigned char length=0;
   uint8_t RHdata[3]={0};
   if(!I2C_Start())	return DISABLE;
   I2C_SendByte(I2C_ADR_W);
    if(!I2C_WaitAck())
	{
    	I2C_Stop();
		return DISABLE;
	}
    I2C_SendByte(TRIG_RH_MEASUREMENT_POLL);
    I2C_WaitAck();
	delay_us(20);
	I2C_Stop();
	do
	{
		DELAY(100);
		I2C_Start();
		I2C_SendByte(I2C_ADR_R);
	}while(!I2C_WaitAck());

	RHdata[0]=I2C_ReceiveByte(); //	printf("%c\r\n",Tdata[0]);
	I2C_Ack();
	RHdata[1]=I2C_ReceiveByte(); //	printf("%c\r\n",Tdata[1]);
	I2C_NoAck();
	I2C_Stop();
	humidityRH = -6.0 + 125.0/65536 * ((float)((((unsigned short int)RHdata[0]<<8)+(unsigned short int)RHdata[1])&0xfff0));
	return ENABLE;
}
